package fr.imag.m2pgi.m2m.geoloc.visualizer;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.LinkedList;

import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.LineArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.swing.JFrame;
import javax.vecmath.Point3d;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3f;

public class Visualisation extends JFrame implements WindowListener, KeyListener {

  SimpleUniverse simpleU;
  TransformGroup View_TransformGroup;
  Transform3D View_Transform3D;

  
  
  Visualisation(LinkedList<LinkedList<Mesure>> superListe) {
    super("Visualisation");
    this.addWindowListener(this);
    this.setLayout(new BorderLayout());

    // creation de la scene java3d
    Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
    simpleU = new SimpleUniverse(canvas);
    BranchGroup visualisation = visua(superListe);
    simpleU.addBranchGraph(visualisation);
    simpleU.getViewingPlatform().setNominalViewingTransform();

//    ViewingPlatform vp = simpleU.getViewingPlatform();
//    View_TransformGroup = vp.getMultiTransformGroup().getTransformGroup(0);
//    View_Transform3D = new Transform3D();
//    View_TransformGroup.getTransform(View_Transform3D);
//    View_Transform3D.setTranslation(new Vector3f(0.0f,0.0f,2.5f));
//    View_TransformGroup.setTransform(View_Transform3D);
//    this.addKeyListener(this);
    
    this.add("Center", canvas);
  }

  BranchGroup visua(final LinkedList<LinkedList<Mesure>> superListe) { 
    BranchGroup visua = new BranchGroup();

    LineArray lPaire = new LineArray(2, LineArray.COORDINATES
        | LineArray.COLOR_3);
    LineArray lImpaire = new LineArray(2, LineArray.COORDINATES
        | LineArray.COLOR_3);
    double z = 0;

    // pour toutes les listes de mesures prises
    for (int i = 0; i < superListe.size(); i++) {

      // on prend la ième liste de mesure
      LinkedList<Mesure> l = superListe.get(i);

      if (i == 0)
        z = 0;
      if (i == superListe.size() - 1)
        z = 1;
      if (0 < i && i < superListe.size() - 1)
        z = (double) i / (double) (superListe.size() - 1);

      // pour toutes les mesures dans cette liste
      // on va calculer les coordonnées
      for (int j = 0; j < l.size(); j++) {

        double x = 0.0;
        double y = 0.0;
        Mesure m = l.get(j);
        double angle = m.getAngle();
        double distance = m.getDistance();

        // (on a un angle et une longueur => calcul trigonométrique

        // calcul pour x
        if (angle > 0.0) {
          x = Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5);
        }
        if (angle == 0.0) {
          x = 0.0;
        }
        if (angle < 0.0) {
          x = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5);
        }

        // calcul pour y
        if (-90.0 < angle && angle < 90.0) {
          y = Math.abs(Math.cos(Math.abs(angle)) * distance / 5);
        }
        if (Math.abs(angle) == 90.0) {
          y = 0.0;
        }
        if (angle < -90.0) {
          y = -Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5);
        }
        if (angle > 90.0) {
          y = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5);
        }

        System.out.println("(" + x + " ; " + y + " ; " + z + ")");

        // on a les coordonnée => ajout dans de la line Array

        // si j est paire : ajout des 1er pour Lpaire
        if (j % 2 == 0) {
          if (j != l.size() - 1) {
            lPaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
            lPaire.setCoordinate(0, new Point3d(x, y, z));
            lPaire.setColor(0, new Color3f(1f, 0f, 0f));
          }

          if (j != 0) {
            lImpaire.setCoordinate(1, new Point3d(x, y, z));
            lImpaire.setColor(1, new Color3f(1f, 0f, 0f));
            visua.addChild(new Shape3D(lImpaire));
          }
        }
        if (j % 2 == 1) {
          if (j != l.size() - 1) {
            lImpaire = new LineArray(2, LineArray.COORDINATES
                | LineArray.COLOR_3);
            lImpaire.setCoordinate(0, new Point3d(x, y, z));
            lImpaire.setColor(0, new Color3f(1f, 0f, 0f));
          }
          lPaire.setCoordinate(1, new Point3d(x, y, z));
          lPaire.setColor(1, new Color3f(1f, 0f, 0f));
          visua.addChild(new Shape3D(lPaire));

        }

      }// fin du parcours de la ième liste

    }// fin du parcour de la liste des listes de mesure

    
    visua.compile();

    return visua;

  }

  public void windowActivated(final WindowEvent e) {
  }

  public void windowClosed(final WindowEvent e) {
  }

  public void windowDeactivated(final WindowEvent e) {
  }

  public void windowDeiconified(final WindowEvent e) {
  }

  public void windowIconified(final WindowEvent e) {
  }

  public void windowOpened(final WindowEvent e) {
  }

  public void windowClosing(final WindowEvent e) {
    System.exit(1);
  }
  
  public void keyPressed(KeyEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("coucou");
    
  }

  public void keyReleased(KeyEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("coucou");
    
  }

  public void keyTyped(KeyEvent arg0) {
    // TODO Auto-generated method stub
    System.out.println("coucou");
    if(arg0.getKeyCode() == KeyEvent.VK_KP_LEFT){
      View_Transform3D.setTranslation(new Vector3f(0.0f,-1.0f,5.0f));
      View_TransformGroup.setTransform(View_Transform3D);
      
    }
    if(arg0.getKeyCode() == KeyEvent.VK_KP_RIGHT){
      
    }
    if(arg0.getKeyCode() == KeyEvent.VK_KP_UP){
      
    }
    if(arg0.getKeyCode() == KeyEvent.VK_KP_DOWN){
      
    }
    
  }

  public static void main(final String args[]) {

    LinkedList<Mesure> liste1 = new LinkedList<Mesure>();
    liste1.add(new Mesure(2.5, -92.0));
    liste1.add(new Mesure(2.23, -45.0));
    liste1.add(new Mesure(2.23, 45.0));
    liste1.add(new Mesure(2.5, 92.0));

    LinkedList<LinkedList<Mesure>> superListe = new LinkedList<LinkedList<Mesure>>();
    superListe.add(liste1);
    superListe.add(liste1);
    superListe.add(liste1);
    superListe.add(liste1);
    superListe.add(liste1);
    superListe.add(liste1);

    Visualisation visu = new Visualisation(superListe);
    visu.addKeyListener(visu);
    visu.setSize(400, 400);
    visu.setVisible(true);
  }

}